package com.ycy.smartcourseselection.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycy.smartcourseselection.common.*;
import com.ycy.smartcourseselection.dto.teacher.*;
import com.ycy.smartcourseselection.entity.*;
import com.ycy.smartcourseselection.exception.CustomException;
import com.ycy.smartcourseselection.mapper.ITeacherMapper;
import com.ycy.smartcourseselection.utils.CommonUtils;
import com.ycy.smartcourseselection.utils.ValidateUtils;
import com.ycy.smartcourseselection.utils.WrapperUtils;
import com.ycy.smartcourseselection.utils.PageUtils;
import com.ycy.smartcourseselection.vo.teacher.FileTchVO;
import com.ycy.smartcourseselection.vo.teacher.HomePageVO;
import com.ycy.smartcourseselection.vo.teacher.TeacherVO;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;

@Service
public class TeacherService extends ServiceImpl<ITeacherMapper, Teacher> {
    // PageUtils<Course, CourseVO> coursePageUtils = new PageUtils<>();
    // // PageUtils<Student, StudentVO> stuPageUtils = new PageUtils<>();
    PageUtils<Teacher, TeacherVO> tchPageUtils = new PageUtils<>();
    @Resource
    private CourseService courseService;
    @Lazy
    @Resource
    private ScoreService scoreService;

    //分页查教师信息
    public ResData<PageResVO<TeacherVO>> findPageTch(FindPageTchDTO findPageTchDTO) {
        PageParamsDTO pageParamsDTO = findPageTchDTO.getPageParams();
        FindAllTchDTO otherParams = findPageTchDTO.getOtherParams();

        //验证pageNum，pageSize
        Integer pageNum = pageParamsDTO.getPageNum();
        Integer pageSize = pageParamsDTO.getPageSize();
        tchPageUtils.validatePageNumPageSize(pageNum, pageSize);

        QueryWrapper<Teacher> wrapper = WrapperUtils.buildAllTchWrapper(otherParams, new QueryWrapper<>());
        QueryWrapper<Teacher> newQueryWrapper = tchPageUtils.buildPageQueryWrapper(pageParamsDTO, wrapper);

        Page<Teacher> basePage = new Page<>(pageNum, pageSize);
        Page<Teacher> resPage = page(basePage, newQueryWrapper);

        ArrayList<TeacherVO> VOList = new ArrayList<>();
        for (Teacher entity : resPage.getRecords()) {
            TeacherVO VO = new TeacherVO();
            BeanUtil.copyProperties(entity, VO);
            VOList.add(VO);
        }

        //构造分页结果
        PageResVO<TeacherVO> pageResVO = tchPageUtils.getConditionResVO(resPage);
        pageResVO.setRows(VOList);

        return ResData.success(pageResVO);
    }
    //增加或修改教师信息
    public ResData<Boolean> saveTch(TeacherDTO teacherDTO) {
        String workId = teacherDTO.getWorkId();
        String tchName = teacherDTO.getName();
        if(StrUtil.isBlank(workId)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"工号不能为空");
        if(StrUtil.isBlank(tchName)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"姓名不能为空");

        QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
        // wrapper.eq("is_resigned",0);
        wrapper.eq("work_id",workId);
        List<Teacher> sameList = list(wrapper);

        Teacher entity = new Teacher();
        BeanUtil.copyProperties(teacherDTO,entity);

        boolean isAdd = StrUtil.isBlank(teacherDTO.getId());
        // if(sameList.size() != 0 && isAdd) throw new CustomException(ResCodeEnum.BAD_REQUEST,"该工号的教师信息已存在");
        if(isAdd) {
            if(sameList.size() != 0) throw new CustomException(ResCodeEnum.BAD_REQUEST,"该学号的学生信息已存在");
            String identityIdMessage = ValidateUtils.identityId(teacherDTO.getIdentityId());
            if(!"".equals(identityIdMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST,identityIdMessage);
            String phoneMessage = ValidateUtils.phone(teacherDTO.getPhone());
            if(!"".equals(phoneMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST,phoneMessage);
            String qqMessage = ValidateUtils.QQ(teacherDTO.getQQ());
            if(!"".equals(qqMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST,qqMessage);
            entity.setPassword(entity.getIdentityId().substring(12));
        }

        if(isAdd) return ResData.success(saveOrUpdate(entity),"添加成功");
        else return ResData.success(saveOrUpdate(entity),"修改成功");
    }
    //批量辞退学生信息
    public ResData<Boolean> falseDeleteTchByIds(List<String> idList) {
        QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", idList);
        List<Teacher> list = list(queryWrapper);

        for (Teacher entity : list) {
            entity.setIsResigned(1);
        }

        return ResData.success(updateBatchById(list), "辞退成功");
    }
    //根据学号查询个人信息
    public ResData<TeacherVO> getInfo(String workId) {
        if(StrUtil.isBlank(workId)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"工号不能为空");

        QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id",workId);
        List<Teacher> list = list(wrapper);

        if(list.size() == 0) throw new CustomException(ResCodeEnum.BAD_REQUEST,"该工号的教师不存在");
        if(list.size() > 1) throw new CustomException(ResCodeEnum.BAD_REQUEST,"错误地存在多个该工号的教师");

        TeacherVO teacherVO = new TeacherVO();
        BeanUtil.copyProperties(list.get(0),teacherVO);
        return ResData.success(teacherVO);
    }
    //重设密码
    public ResData<Boolean> modifyPwd(ForgetTchPwdDTO forgetTchPwdDTO) {
        String id = forgetTchPwdDTO.getId();
        String password = forgetTchPwdDTO.getPassword();

        if(StrUtil.isBlank(id)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"工号不能为空");
        if(StrUtil.isBlank(password)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"新密码不能为空");

        Teacher teacher = new Teacher();
        BeanUtil.copyProperties(forgetTchPwdDTO,teacher);

        return ResData.success(saveOrUpdate(teacher));
    }
    //首页图表统计信息
    public ResData<HomePageVO> findHomePage(String workId) {
        if (StrUtil.isBlank(workId)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "工号不能为空");

        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id",workId);
        wrapper.orderByAsc("school_year");
        // wrapper.orderByDesc("grade");
        wrapper.select("school_year","total_hours","selected_num","max_person","id");
        List<Course> courseList = courseService.list(wrapper);

        HomePageVO homePageVO = new HomePageVO();

        int realityTotalStuNum = 0;
        int theoryTotalStuNum = 0;
        int totalHours = 0;
        ArrayList<String> idList = new ArrayList<>();
        LinkedHashSet<String> axisX = new LinkedHashSet<>();  //LinkedHashSet能取唯一值，并保持插入顺序。普通HashSet按照hash值排列，不能保持插入顺序。
        for (Course course: courseList) {
            realityTotalStuNum += course.getSelectedNum();
            theoryTotalStuNum += course.getMaxPerson();
            totalHours += course.getTotalHours();
            axisX.add(course.getSchoolYear());
            idList.add(course.getId());
        }

        ArrayList<Integer> axisY = new ArrayList<>();
        // ArrayList<String> sortedAxisX = new ArrayList<>(axisX);
        // Collections.sort(sortedAxisX);
        for (String schoolYear : axisX) {
            int perSchoolYearStuCount = 0;
            for (Course course : courseList) {
                if (schoolYear.equals(course.getSchoolYear())) perSchoolYearStuCount += course.getSelectedNum();
            }
            axisY.add(perSchoolYearStuCount);
        }

        QueryWrapper<Score> scoreWrapper = new QueryWrapper<>();
        scoreWrapper.in(idList.size() != 0,"course_id",idList);
        scoreWrapper.select("score");
        List<Score> scoreList = scoreService.list(scoreWrapper);
        int passStuNum = 0;
        for (Score score: scoreList) if(score.getScore() >= 60) passStuNum++;

        homePageVO.setPassStuNum(passStuNum);
        homePageVO.setTotalCourseNum(courseList.size());
        homePageVO.setTotalHours(totalHours);
        homePageVO.setRealityTotalStuNum(realityTotalStuNum);
        homePageVO.setTheoryTotalStuNum(theoryTotalStuNum);
        homePageVO.setPerSchoolYearChartX(axisX);
        homePageVO.setPerSchoolYearChartY(axisY);

        return ResData.success(homePageVO);
    }
    //excel表导入教师信息
    public ResData<Boolean> tchInfoImport(MultipartFile file) {
        if (file == null) throw new CustomException(ResCodeEnum.BAD_REQUEST, "文件不能为空");

        ArrayList<Teacher> importList = new ArrayList<>();
        List<FileTchVO> fileTchList;
        try {
            InputStream inputStream = file.getInputStream();
            ExcelReader excelReader = ExcelUtil.getReader(inputStream);
            fileTchList = excelReader.readAll(FileTchVO.class);
            inputStream.close();
            excelReader.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(ResCodeEnum.SERVER_ERROR, "导入教师信息表格失败");
        }

        LinkedList<String> workIdList = new LinkedList<>();
        for (FileTchVO fileTchVO : fileTchList) workIdList.addFirst(fileTchVO.getWorkId());

        QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
        wrapper.in("work_id", workIdList);
        wrapper.select("work_id");
        List<Teacher> tchList = list(wrapper);
        if (tchList.size() != 0) {
            LinkedList<String> sameWorkIdList = new LinkedList<>();
            for (Teacher teacher : tchList) sameWorkIdList.addFirst(teacher.getWorkId());
            throw new CustomException(ResCodeEnum.BAD_REQUEST, "系统中已存在如下工号的教师：", sameWorkIdList.toString());
        }

        for (FileTchVO fileTchVO : fileTchList) {
            String workId = fileTchVO.getWorkId();
            String name = fileTchVO.getName();
            String phone = fileTchVO.getPhone();
            String sex = fileTchVO.getSex();
            String qq = fileTchVO.getQQ();
            String isAdmin = fileTchVO.getIsAdmin();
            String isResigned = fileTchVO.getIsResigned();
            String identityId = fileTchVO.getIdentityId();

            if (StrUtil.isBlank(workId)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有教师的工号为空,请检查");
            if (StrUtil.isBlank(name)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有教师的姓名为空,请检查");
            if (StrUtil.isBlank(phone)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有教师联系电话为空,请检查");
            if (StrUtil.isBlank(sex)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有教师性别为空,请检查");
            if (StrUtil.isBlank(qq)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有教师QQ为空,请检查");
            if (StrUtil.isBlank(identityId)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有教师身份证号为空,请检查");

            String errMessage = CommonUtils.validateIdentityIdPhoneQQ(identityId, phone, qq);
            if (!"".equals(errMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST, errMessage);

            Teacher teacher = new Teacher();
            teacher.setPassword(identityId.substring(12));
            if ("男".equals(sex)) teacher.setSex(1);
            else teacher.setSex(0);
            if ("是".equals(isAdmin)) teacher.setIsAdmin(1);
            else teacher.setIsAdmin(0);
            if ("是".equals(isResigned)) teacher.setIsResigned(1);
            else teacher.setIsResigned(0);

            BeanUtils.copyProperties(fileTchVO, teacher, "sex", "isAdmin", "isResigned");

            importList.add(teacher);
        }

        return ResData.success(saveBatch(importList));
    }
    //表格导出(导出不需要返回参数)
    public void tchInfoExport(HttpServletResponse response, FindAllTchDTO findAllTchDTO) {
        QueryWrapper<Teacher> newWrapper = WrapperUtils.buildAllTchWrapper(findAllTchDTO, new QueryWrapper<>());
        List<Teacher> tchList = list(newWrapper);

        //1. 所有学生列表，每一项处理后拷贝到 ExportVO的列表中
        ArrayList<FileTchVO> exportVOList = new ArrayList<>();
        for (int i = 0; i < tchList.size(); i++) {
            Teacher teacher = tchList.get(i);
            FileTchVO exportVO = new FileTchVO();
            exportVO.setOrder(i + 1);
            if (teacher.getSex() == 1) exportVO.setSex("男");
            else exportVO.setSex("女");
            if (teacher.getIsAdmin() == 1) exportVO.setIsAdmin("是");
            else exportVO.setIsAdmin("否");
            if (teacher.getIsResigned() == 1) exportVO.setIsResigned("是");
            else exportVO.setIsResigned("否");

            BeanUtils.copyProperties(teacher, exportVO, "sex", "isAdmin", "isResigned");
            exportVOList.add(exportVO);
        }

        //2. 在UserExportVO类中给每个属性用 @Alias(value = "中文名")的注解添加中文名

        try {
            //3. 用ExcelUtil获取 excelWriter对象
            ExcelWriter excelWriter = ExcelUtil.getWriter(true);

            //4.将UserExportVO的列表写入excelWriter中，并添加中文名表头
            excelWriter.write(exportVOList, true);

            //5.设置浏览器响应的格式
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = URLEncoder.encode("教师信息", "UTF-8");  //设置文件名称,并进行编码
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");  //将文件名设置到 response的 header中

            //6.用response来货如输出流
            ServletOutputStream outputStream = response.getOutputStream();

            //7. 将输出流刷新到 excelWriter对象中，并关闭输出流和excelWriter对象
            excelWriter.flush(outputStream, true);
            outputStream.close();
            excelWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(ResCodeEnum.SERVER_ERROR, "导出教师信息表格失败");
        }
    }



    //公共方法  -------------------------------


}
